#include "minimusic.h"
#include "ui_minimusic.h"
#include "listitembox.h"
#include <btform.h>

#include <QPushButton>
#include <QMouseEvent>
#include <QDebug>
#include <QGraphicsDropShadowEffect>
#include <QJsonObject>
#include <QFileDialog>
#include <QMediaPlaylist>

MiniMusic::MiniMusic(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MiniMusic)
{
    ui->setupUi(this);

    initUI();

    initPlayer();
    connectSianalSlots();
}

MiniMusic::~MiniMusic()
{
    delete ui;
}

void MiniMusic::initUI()
{
    // 设置⽆边框窗⼝，即窗⼝将来没有标题栏
    this->setWindowFlag(Qt::WindowType::FramelessWindowHint);

    // 设置窗口的阴影效果

    // 重点：设置边距，防止阴影被裁剪或超界
    this->setContentsMargins(10, 10, 10, 10);
    setAttribute(Qt::WA_TranslucentBackground);// 透明
    QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect(this);

    shadowEffect->setOffset(0, 0); // 设置阴影偏离
    shadowEffect->setColor(QColor(0, 0, 0, 160)); // 设置阴影颜色
    shadowEffect->setBlurRadius(10); // 设置阴影的模糊半径
    this->setGraphicsEffect(shadowEffect);

    ui->rec->seticon(":/images/rec.png", "推荐", 0);
    ui->audio->seticon(":/images/radio.png", "电台", 1);
    ui->music->seticon(":/images/music.png", "⾳乐馆", 2);
    ui->like->seticon(":/images/like.png", "我喜欢", 3);
    ui->local->seticon(":/images/local.png", "本地下载", 4);
    ui->recent->seticon(":/images/recent.png", "最近播放", 5);

    // 本地下载BtForm动画默认显⽰
     ui->local->showAnimal();
     ui->stackedWidget->setCurrentIndex(4);
     currentPage = ui->localPage;
    // 初始化推荐页面
     srand(time(NULL));
     ui->recMusicBox->initRecBoxUi(RandomPicture(), 1);
     ui->supplyMusicBox->initRecBoxUi(RandomPicture(), 2);

     // 设置我喜欢、本地⾳乐、最近播放⻚⾯
     ui->likePage->setMusicListType(PageType::LIKE_PAGE);
     ui->likePage->setCommonPageUI("我喜欢", ":/images/ilikebg.png");

     ui->localPage->setMusicListType(PageType::LOCAL_PAGE);
     ui->localPage->setCommonPageUI("本地⾳乐", ":/images/localbg.png");

     ui->recentPage->setMusicListType(PageType::HISTORY_PAGE);
     ui->recentPage->setCommonPageUI("最近播放", ":/images/recentbg.png");

     // 播放控制区按钮图标设定
     ui->play->setIcon(QIcon(":images/play_2.png"));
     ui->playMode->setIcon(QIcon(":/images/shuffle_2.png"));
     volumeTool = new VolumeTool(this);

}

void MiniMusic::initPlayer()
{
    // 1. 初始化媒体播放类对象
    player = new QMediaPlayer(this);
    playList = new QMediaPlaylist(this);

    // 2. 设置默认播放模式
    playList->setPlaybackMode(QMediaPlaylist::Random);

    // 3. 将播放列表设置到播放媒体对象中
    player->setPlaylist(playList);

    // 4.设置默认音量大小
    player->setVolume(20);

    // 关联QMediaPlayer的信号
    connect(player, &QMediaPlayer::stateChanged, this, &MiniMusic::onPlayerStateChanged);

    connect(playList, &QMediaPlaylist::playbackModeChanged, this, &MiniMusic::onPlaybackModeChanged);

    connect(playList, &QMediaPlaylist::currentIndexChanged, this, &MiniMusic::OnCurrentIndexChanged);

    connect(player, &QMediaPlayer::durationChanged, this, &MiniMusic::onDurationChanged);

    connect(player, &QMediaPlayer::positionChanged, this, &MiniMusic::onPositionChanged);
}

void MiniMusic::connectSianalSlots()
{
    // 关联btform的信号和处理该信号的槽函数
    connect(ui->rec, &btForm::btClick, this, &MiniMusic::onBtFormClick);
    connect(ui->audio, &btForm::btClick, this, &MiniMusic::onBtFormClick);
    connect(ui->music, &btForm::btClick, this, &MiniMusic::onBtFormClick);
    connect(ui->like, &btForm::btClick, this, &MiniMusic::onBtFormClick);
    connect(ui->local, &btForm::btClick, this, &MiniMusic::onBtFormClick);
    connect(ui->recent, &btForm::btClick, this, &MiniMusic::onBtFormClick);

    connect(ui->likePage, &CommonPage::updataLikeMusic, this, &MiniMusic::onUpdateLikeMusic);
    connect(ui->localPage, &CommonPage::updataLikeMusic, this, &MiniMusic::onUpdateLikeMusic);
    connect(ui->recentPage, &CommonPage::updataLikeMusic, this, &MiniMusic::onUpdateLikeMusic);

    // 播放控制区的信号和槽函数关联
    connect(ui->play, &QPushButton::clicked, this, &MiniMusic::onPlayMusic);
    connect(ui->playUp, &QPushButton::clicked, this, &MiniMusic::onPlayUpClicked);
    connect(ui->playDown, &QPushButton::clicked, this, &MiniMusic::onPlayDownClicked);
    connect(ui->playMode, &QPushButton::clicked, this, &MiniMusic::onPlaybackModeClicked);

    // 播放所有音乐
    connect(ui->likePage, &CommonPage::playAll, this, &MiniMusic::onPlayAll);
    connect(ui->localPage, &CommonPage::playAll, this, &MiniMusic::onPlayAll);
    connect(ui->recentPage, &CommonPage::playAll, this, &MiniMusic::onPlayAll);

    // 处理likePage、localPage、recentPage中双击ListItemBox双击
    connect(ui->likePage, &CommonPage::playMusicByIndex, this, &MiniMusic::playMusicByIndex);
    connect(ui->localPage, &CommonPage::playMusicByIndex, this, &MiniMusic::playMusicByIndex);
    connect(ui->recentPage, &CommonPage::playMusicByIndex, this, &MiniMusic::playMusicByIndex);

    // 处理声音的
    connect(volumeTool, &VolumeTool::setMusicMuted, this, &MiniMusic::setPlayerMuted);

    // 处理音量大小
    connect(volumeTool, &VolumeTool::setMusicVolume, this, &MiniMusic::setPlayerVolume);

    // 进度条管理时间
    connect(ui->processBar, &MusicSlider::setMusicSliderPosition, this, &MiniMusic::onMusicSliderChanged);
}

void MiniMusic::onUpdateLikeMusic(bool isLike, QString musicId)
{
    // 修改状态
    auto it = musicList.findMusicByMusicId(musicId);
    if(it != musicList.end())
    {
        it->setIslike(isLike);
    }

    ui->likePage->reFresh(musicList);
    ui->localPage->reFresh(musicList);
    ui->recentPage->reFresh(musicList);

}

QJsonArray MiniMusic::RandomPicture()
{
    // 推荐⽂本 + 推荐图⽚路径
    QVector<QString> vecImageName;
    vecImageName << "001.png" << "003.png" << "004.png" << "005.png" << "006.png" << "007.png"
                 << "008.png" << "009.png" << "010.png" << "011.png" << "012.png" << "013.png"
                 << "014.png" << "015.png" << "016.png" << "017.png" << "018.png" << "019.png"
                 << "020.png" << "021.png" << "022.png" << "023.png" << "024.png" << "025.png"
                 << "026.png" << "027.png" << "028.png" << "029.png" << "030.png" << "031.png"
                 << "032.png" << "033.png" << "034.png" << "035.png" << "036.png" << "037.png"
                 << "038.png" << "039.png" << "040.png";

    std::random_shuffle(vecImageName.begin(), vecImageName.end());

     // 001.png
     // path: ":/images/rec/"+vecImageName[i];
     // text: "推荐-001"
     QJsonArray objArray;
     for(int i = 0; i < vecImageName.size(); ++i)
     {
         QJsonObject obj;
         obj.insert("path", ":/images/rec/"+vecImageName[i]);
         // arg(i, 3, 10, QCchar('0'))
         // i：要放⼊%1位置的数据
         // 3: 三位数
         // 10：表⽰⼗进制数
         // QChar('0')：数字不够三位，前⾯⽤字符'0'填充
         QString strText = QString("推荐-%1").arg(i, 3, 10, QChar('0'));
         obj.insert("text", strText);
         objArray.append(obj);
     }
     return objArray;
}


void MiniMusic::on_quit_clicked()
{
    close();
}

void MiniMusic::onBtFormClick(int pageId)
{
    // 1.获取当前⻚⾯所有btFrom按钮类型的对象
     QList<btForm*> btFormList = this->findChildren<btForm*>();
    // 2.遍历所有对象, 如果不是当前id的按钮,则把之前设置的背景颜⾊清除掉
     for(auto btForm : btFormList)
     {
         if(btForm->getId() != pageId)
         {
             btForm->clearBg();
         }
     }
    // 3.设置当前栈空间显⽰⻚⾯ui->stackedWidget->setCurrentIndex(id - 1);
     ui->stackedWidget->setCurrentIndex(pageId);
}

void MiniMusic::mousePressEvent(QMouseEvent *event)// 鼠标单击
{
    if(event->button() == Qt::LeftButton)
    {
//        event->globalPos();// ⿏标按下事件发⽣时，光标相对于屏幕左上⻆位置
//        frameGeometry().topLeft(); //⿏标按下事件发⽣时，窗⼝左上⻆位置
//        geometry();
//        frameGeometry();
        dragPosition = event->globalPos() - geometry().topLeft();
         return;
    }
    QWidget::mousePressEvent(event);
}

void MiniMusic::mouseMoveEvent(QMouseEvent *event)// 鼠标移动
{
    if(event->buttons() == Qt::LeftButton)
    {
        move(event->globalPos() - dragPosition);
        return;
    }
    QWidget::mouseMoveEvent(event);
}

void MiniMusic::on_volume_clicked()
{
     // 先要调整窗⼝的显⽰位置，否则该窗⼝在主窗⼝的左上⻆
     // 1. 获取该按钮左上⻆的图标
     QPoint point = ui->volume->mapToGlobal(QPoint(0,0));
     // 2. 计算volume窗⼝的左上⻆位置
     // 让该窗⼝显⽰在⿏标点击的正上⽅
     // ⿏标位置：减去窗⼝宽度的⼀半，以及⾼度恰巧就是窗⼝的左上⻆
     QPoint volumeLeftTop = point - QPoint(volumeTool->width()/2, volumeTool->height());
     // 微调窗⼝位置
     volumeLeftTop.setX(volumeLeftTop.x()+15);
     volumeLeftTop.setY(volumeLeftTop.y()+30);

     // 3. 移动窗⼝位置
     volumeTool->move(volumeLeftTop);
     // 4. 将窗⼝显⽰出来
     volumeTool->show();
}

void MiniMusic::on_addlocal_clicked()
{
    QFileDialog fileDialog(this);

    // 设置窗口标题
    fileDialog.setWindowTitle("添加本地下载音乐");

    // 设置文件对话框默认的打开文件
    QDir dir(QDir::currentPath());
    dir.cdUp();
    QString projectPath = dir.path();
    projectPath += "/project_experience/MiniMusic/musics/";
    fileDialog.setDirectory(projectPath);

    // 设置一次打开多个
    fileDialog.setFileMode(QFileDialog::ExistingFiles);
//    // 通过文件过滤
//    fileDialog.setNameFilter("代码文件(*.h *.c *.cpp *.hpp)");

    // 通过文件的MIME类型来过滤
    QStringList mimeTypeFileters;
//    mimeTypeFileters << "image/jpeg"
//                     << "image/png";

    mimeTypeFileters << "application/octet-stream"; // All(*)
    fileDialog.setMimeTypeFilters(mimeTypeFileters);




    if(QDialog::Accepted == fileDialog.exec())
    {
        // 将CommonPage切换到本地下载的页面
        ui->stackedWidget->setCurrentIndex(4);

        // 获取选中文件
        QList<QUrl> fileUrls = fileDialog.selectedUrls();

        // fileUrls: 内部存放大的是刚刚选中的文件的url路径
        // 需要将文件信息填充到本地下载

        // 将所有音乐添加到音乐列表，MusicList
        // musicList中管理的是解析之后的Music对象
        musicList.addMusicsByUrl(fileUrls);

        ui->localPage->reFresh(musicList);

        // 将localPage中的歌曲添加到媒体播放列表中
        ui->localPage->addMusicToPlaylist(musicList, playList);
    }
}
/////////////////////////////////////////////////////////////////////////////////
// 播放控制类的
void MiniMusic::onPlayMusic()
{
    if(QMediaPlayer::PlayingState == player->state())
    {
        //播放中点击，应该暂停
        player->pause();
//        ui->play->setIcon(QIcon(":/images/play3.png"));
    }
    else if(QMediaPlayer::PausedState == player->state())
    {
        // 如果是暂停状态，按下播放键，继续开始播放
        player->play();
//        ui->play->setIcon(QIcon(":/images/play_on.png"));
    }
    else if(QMediaPlayer::StoppedState == player->state())
    {
        // 刚开始默认为停止状态，当点击播放按钮时，直接播放即可
        player->play();
//        ui->play->setIcon(QIcon(":/images/play_on.png"));
    }
    else
    {
        qDebug() << player->errorString();
    }
}

void MiniMusic::onPlayUpClicked()
{
    playList->previous();
}

void MiniMusic::onPlayDownClicked()
{
    playList->next();
}

void MiniMusic::onPlaybackModeClicked()
{
    // 根据当前的播放模式切换到下一个播放模式
    // 设置ToolTip提示
    // 列表循环---->随机播放---->单曲循环
    // 当状态发生改变的时候，还需要修改按钮上的图标
    if(playList->playbackMode() == QMediaPlaylist::Loop)
    {
        // 随机播放
        playList->setPlaybackMode(QMediaPlaylist::Random);
        ui->playMode->setToolTip("随机循环");
    }
    else if(playList->playbackMode() == QMediaPlaylist::Random)
    {
        //单曲循环
        playList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
        ui->playMode->setToolTip("单曲循环");
    }
    else if(playList->playbackMode() == QMediaPlaylist::CurrentItemInLoop)
    {
        playList->setPlaybackMode(QMediaPlaylist::Loop);
        ui->playMode->setToolTip("列表循环");
    }
    else
    {
        qDebug() << "暂不支持";
    }
}

void MiniMusic::onPlayerStateChanged()
{
    if(player->state() == QMediaPlayer::PlayingState)
    {
        ui->play->setIcon(QIcon(":/images/play_on.png"));
    }
    else
    {
        ui->play->setIcon(QIcon(":/images/play3.png"));
    }
}

void MiniMusic::onPlaybackModeChanged(QMediaPlaylist::PlaybackMode playbackMode)
{
    if(playbackMode == QMediaPlaylist::Loop)
    {
        ui->playMode->setIcon(QIcon(":/images/list_play.png"));
    }
    else if(playbackMode == QMediaPlaylist::Random)
    {
        ui->playMode->setIcon(QIcon(":/images/shuffle_2.png"));
    }
    else if(playbackMode == QMediaPlaylist::CurrentItemInLoop)
    {
        ui->playMode->setIcon(QIcon(":/images/single_play.png"));
    }
    else
    {
        qDebug() << "暂不支持";
    }
}

void MiniMusic::OnCurrentIndexChanged(int index)
{
    QString musicId = currentPage->getMusicIdByIndex(index);

    auto it = musicList.findMusicByMusicId(musicId);
    if(it != musicList.end())
    {
        it->setIsHistory(true);
    }

    ui->recentPage->reFresh(musicList);
}

void MiniMusic::onDurationChanged(qint64 duration)
{
//    分：duration/1000/60;
//    秒：duration/1000%60;
    totalTime = duration;
    ui->totalTime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10, QChar('0'))
                                           .arg(duration/1000%60, 2, 10, QChar('0')));
}

void MiniMusic::onPositionChanged(qint64 position)
{
    ui->currentTime->setText(QString("%1:%2").arg(position/1000/60, 2, 10, QChar('0'))
                                             .arg(position/1000%60, 2, 10, QChar('0')));
    ui->processBar->setStep(position/(float)totalTime);
}

void MiniMusic::onMusicSliderChanged(float ration)
{
    qint64 duration = totalTime*ration;
    ui->currentTime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10, QChar('0'))
                                             .arg(duration/1000%60, 2, 10, QChar('0')));
    player->setPosition(duration);
}

void MiniMusic::onPlayAll(PageType pageType)
{
    // 通过pageType找到对应的CommonPage页面
    CommonPage* page = ui->localPage;
    switch (pageType)
    {
    case PageType::LIKE_PAGE:
        page = ui->likePage;
        break;
    case PageType::LOCAL_PAGE:
        page = ui->localPage;
        break;
    case PageType::HISTORY_PAGE:
        page = ui->recentPage;
        break;
    default:
        qDebug() << "暂不支持的页面";
    }


    //page要记录的是播放的页面
    playAllMusicOfCommonPage(page, 0);
}

void MiniMusic::playAllMusicOfCommonPage(CommonPage *page, int index)
{
    currentPage = page;
    // 清空之前的页面
    playList->clear();

    //添加当前要播放的页面
    page->addMusicToPlaylist(musicList, playList);

    // 从第0首开始播放
    playList->setCurrentIndex(index);

    player->play();
}

void MiniMusic::playMusicByIndex(CommonPage *page, int index)
{
    playAllMusicOfCommonPage(page, index);
}

void MiniMusic::setPlayerMuted(bool isMuted)
{
    player->setMuted(isMuted);
}

void MiniMusic::setPlayerVolume(int volume)
{
    player->setVolume(volume);
}


























